using System;
using System.Collections;
using System.Xml;

using MediaWikiEngine.Command;
using MediaWikiEngine.Domain;
using System.Collections.Generic;


namespace MediaWikiEngine
{
	/// <summary>
	/// An XML-driven script for controlling a MediaWiki-based wiki.
	/// </summary>
	public class ConnectionScript
	{
        Dictionary<string, Type> _commands = new Dictionary<string, Type>();
        XmlDocument _script;

		public ConnectionScript(XmlDocument script) : this()
		{
            _script = script;
		}

        public ConnectionScript()
		{
            _commands.Add("wiki:login", typeof(Login));
            _commands.Add("wiki:getpage", typeof(GetPage));
            _commands.Add("wiki:savepage", typeof(SavePage));
            _commands.Add("wikipage:replacecontent", typeof(ReplaceContent));
            _commands.Add("bot:set", typeof(Bot_Set));
            _commands.Add("wiki:uploadfile", typeof(UploadFile));
            _commands.Add("wiki:updatewatch", typeof(UpdateWatch));
		}


        public void Run()
        {
            Run(_script);
        }

		public void Run(XmlDocument script)
		{
			Hashtable globalParameters = new Hashtable();
			Hashtable localParameters = new Hashtable();

			WikiConnection conn = null;

			Config c = new Config(script);

			foreach (CommandDescriptor cmd in c.Commands)
			{
				foreach (Condition cond in cmd.Conditions)
				{
					if (false == cond.Evaluate(globalParameters, localParameters))
						throw new ApplicationException("condition didn't match");
				}

				CommandParams parameters = new CommandParams();

				foreach (InputParameter input in cmd.InputParameters)
				{
					if (input.Value.StartsWith("$$"))
					{
						parameters[input.Name] = globalParameters[input.Value];
					}
					else if (input.Value.StartsWith("$"))
					{
						parameters[input.Name] = localParameters[input.Value];
					}
					else
						parameters[input.Name] = input.Value;
				}

				switch (cmd.CommandID)
				{
					case "bot:exit":
						Console.WriteLine("Exiting");
						return;
					case "bot:connect":
						conn = new WikiConnection(globalParameters["$$wikihost"].ToString());
						Console.WriteLine("Connecting");
						break;
					default:
						Console.WriteLine("Command: {0}", cmd.CommandID);
						BaseCommand baseCmd = (BaseCommand) Activator.CreateInstance((Type) _commands[cmd.CommandID], new object[] { parameters, conn });
						CommandResult results = baseCmd.Execute();

						foreach (OutputParameter output in cmd.OutputParameter)
						{
							if (output.Target.StartsWith("$$"))
							{
								globalParameters[output.Target] = results[output.Name];
							}
							else if (output.Target.StartsWith("$"))
							{
								localParameters[output.Target] = results[output.Name];
							}
						}
						
						break;
				}

			}


		}
	}
}
